﻿package com.ufenlei.LTS{
	import flash.media.*;
	import flash.events.*;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.net.URLRequest;
	

	public class SoundFacade extends EventDispatcher {
		public var s:Sound;
		public var sc:SoundChannel;
		public var url:String;
		public var bufferTime:int=1000;
		private var _volume:Number;

		public var isLoaded:Boolean=false;
		public var isReadyToPlay:Boolean=false;
		public var isPlaying:Boolean=false;
		public var isStreaming:Boolean=true;
		public var autoLoad:Boolean=false;
		public var autoPlay:Boolean=true;
		public var pausePosition:int=0;

		public static const PLAY_PROGRESS:String="playProgress";
		public static const PLAY_STOP:String="PlayStop";
		public static const PLAY_PAUSE:String = "PlayPause";
		public var progressInterval:int=1000;
		public var playTimer:Timer;

		public function SoundFacade(streaming:Boolean=true,bufferTime:int=-1):void {
			//this.url=soundUrl;
			// Sets Boolean values that determine the behavior of this object 
			//this.autoLoad=autoLoad;
			//this.autoPlay=autoPlay;
			this.isStreaming=streaming;

			// Defaults to the global bufferTime value 
			if (bufferTime<0) {
				bufferTime=SoundMixer.bufferTime;
			}

			// Keeps buffer time reasonable, between 0 and 30 seconds 
			this.bufferTime=Math.min(Math.max(0,bufferTime),30000);
		}
		public function get volume():Number{
			if(sc is SoundChannel){
				return sc.soundTransform.volume;
			}else{
				return _volume;
			}
		}
		public function set volume(s:Number):void{
			if(sc is SoundChannel){
				var stf:SoundTransform = sc.soundTransform;
				stf.volume = s;
				sc.soundTransform = stf;
				_volume = volume;
			}else{
				_volume = s;
			}
		}
		public function load(soundUrl:String):void {
			this.url=soundUrl;
			trace("load",soundUrl);

			if (this.isPlaying) {
				this.stop();
				this.s.close();
			}
			this.isLoaded=false;

			this.s=new Sound();
			this.s.addEventListener(ProgressEvent.PROGRESS,onLoadProgress);
			this.s.addEventListener(Event.OPEN,onLoadOpen);
			this.s.addEventListener(Event.COMPLETE,onLoadComplete);
			this.s.addEventListener(Event.ID3,onID3);
			this.s.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
			this.s.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onIOError);

			var req:URLRequest=new URLRequest(this.url);

			var context:SoundLoaderContext=new SoundLoaderContext(this.bufferTime,true);
			this.s.load(req,context);
		}
		public function onID3(event:Event):void {

		}
		public function onIOError(event:Event):void {
			trace("ioError",event);
		}
		public function onPlayComplete(event:Event):void {

		}
		public function onLoadOpen(event:Event):void {
			if (this.isStreaming) {
				this.isReadyToPlay=true;
				if (this.autoPlay) {
					this.play();
				}
			}
			this.dispatchEvent(event.clone());
		}

		public function onLoadProgress(event:ProgressEvent):void {
			this.dispatchEvent(event.clone());
		}

		public function onLoadComplete(event:Event):void {
			this.isReadyToPlay=true;
			this.isLoaded=true;
			this.dispatchEvent(event.clone());

			if (autoPlay&&! isPlaying) {
				play();
			}
		}
		public function play(pos:int=0):void {
			if (! this.isPlaying) {
				if (this.isReadyToPlay) {
					this.sc=this.s.play(pos);
					this.sc.addEventListener(Event.SOUND_COMPLETE,onPlayComplete);
					this.isPlaying=true;

					this.playTimer=new Timer(this.progressInterval);
					this.playTimer.addEventListener(TimerEvent.TIMER,onPlayTimer);
					this.playTimer.start();
				}
			}
		}
		public function onPlayTimer(event:TimerEvent):void {
			var estimatedLength:int = Math.ceil(this.s.length/this.s.bytesLoaded*this.s.bytesTotal);
			var progEvent:ProgressEvent=new ProgressEvent(PLAY_PROGRESS,false,false,this.sc.position,estimatedLength);
			this.dispatchEvent(progEvent);
		}
		public function stop(pos:int=0):void {
			if (this.isPlaying) {
				this.pausePosition=pos;
				this.sc.stop();
				this.playTimer.stop();
				this.isPlaying=false;
				if(pos == 0){
					var stopEvent:Event=new Event(PLAY_STOP);
					this.dispatchEvent(stopEvent);
				}else{
					var pauseEvent:Event=new Event(PLAY_PAUSE);
					this.dispatchEvent(pauseEvent);
				}
			}
		}
		public function pause():void {
			stop(this.sc.position);
		}
		public function resume():void {
			play(this.pausePosition);
		}
	}
}